<template>
    <div class="terminal">
      <div ref="terminal"></div>
    </div>
</template>
<script>
  import { Terminal } from 'xterm'
  import { FitAddon } from 'xterm-addon-fit'
  import 'xterm/css/xterm.css'
  import 'xterm/lib/xterm.js'
  import { mapGetters } from 'vuex'

  export default {
    props: {
      id: {
        type: String
      },
      vId: {
        type: String
      },
      activeId: {
        type: String
      }
    },
    data() {
      return {
        term: new Terminal(),
        container: null,
        socket: ''
      }
    },
    created() {
      this.initXterm()
    },
    computed: {
      ...mapGetters(['token'])
    },
    watch: {
      activeId(){
        if (this.vId === this.activeId) {
          setTimeout(() => this.term.focus())
        }
      }
    },
    methods: {
      read_as_text(msg) {
        const reader = new window.FileReader()
        reader.readAsText(msg, 'utf-8')
        reader.onload = () => this.term.write(reader.result)
      },
      initXterm() {
        if (this.term) {
          this.term.dispose()
        }

        // 初始化一个终端界面容器
        this.term = new Terminal()

        // 自适应屏幕大小
        const fitPlugin = new FitAddon()
        this.term.loadAddon(fitPlugin)

        // 连接websocket
        const wsUrl = this.getWsUrl()
        this.socket = new WebSocket(wsUrl)

        // 接收并渲染数据
        this.socket.onmessage = e => this.read_as_text(e.data)

        // 初始化界面
        this.socket.onopen = () => {
          this.term.open(this.$refs.terminal)
          this.term.focus()
          fitPlugin.fit()
        }

        // 关闭websocket
        this.socket.onclose = e => {
          if (e.code === 3333) {
            window.location.href = 'about:blank'
            window.close()
          } else {
            setTimeout(() => this.term.write('\r\nConnection is closed.\r\n'), 200)
          }
        }

        // 向服务器发送数据
        this.term.onData(data => {
          //这里key值是你输入的值，数据格式order一定要找后端要！！！！
          let order = {
            data: data
          }
          this.socket.send(JSON.stringify(order))
        })

        // 检测屏幕大小改变终端大小
        this.term.onResize(({ cols, rows }) => {
          this.socket.send(JSON.stringify({ resize: [cols, rows] }))
        })
        window.onresize = () => fitPlugin.fit()
      },
      // 获取websocket连接地址
      getWsUrl() {
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
        const urlFamily = window.location.host.split(':')
        const hostname = urlFamily[0] // "192.168.0.20";
        let urlPort = urlFamily.length === 2 ? Number(urlFamily[1]) : null
        if (urlPort === 81) {
          urlPort = 9001
        }
        return `${protocol}//${hostname}${urlPort ? ':' + urlPort : ''}${urlPort !== 9001 ? '/api' : ''}/ws/ssh/${this.id}/?x-token=${this.token}`
      }
    }
  }

</script>

<style lang="less">
  .terminal {
    flex: 1;
    display: flex;
    background-color: #000;
    padding-left: 5px;
  }

  .terminal > div {
    flex: 1
  }
</style>